#ifndef EVOLUTION_H_INCLUDED
#define EVOLUTION_H_INCLUDED

#include <fstream>
#include "../input/input.h"
#include "evolutionelement.h"

class Evolution {
    private:
        Input& input;
        // reference to the input object used in this evolution
        unsigned int amountOfEvolutionElements;
        // no comment
        unsigned int amountOfFormulasToCreatePerElement;
        // no comment
        unsigned int sizeOfNewCreatedFormulas;
        // no comment
        EvolutionElement** evoElements;
        // our evo-Elements
    public:
        Evolution(  Input& myInput,
                    unsigned int& myAmountOfEvolutionElements,
                    unsigned int& myAmountOfFormulasPerElement,
                    unsigned int& mySizeOfNewCreatedFormulas);
        // basic constructor
        ~Evolution();
        // basic destructor
        void run(unsigned int& amountOfRounds, bool output);
        // run this evolution!
        inline void doSomeRounds(const unsigned int& amountOfRounds, bool output) {
            for(unsigned int i=amountOfEvolutionElements; i--;) {
                evoElements[i]->run(amountOfRounds);
            }
            if(output) {
                std::cout<<"\nI allready reached: ";
                std::cout << evoElements[0]->getBestFitnessScore();
            }
        };
        // does the amount of rounds to all its EvolutionElements
        inline void sort() {
            BubbleSort<EvolutionElement>::sort(evoElements, amountOfEvolutionElements);
        };
        // sorts its EvolutionElements
        void recombine();
        // does recombination
        void saveBestResult();
        // writes the best result into a file
        void printBestResult();
        // print the final best result to console
};

#endif // EVOLUTION_H_INCLUDED
